/* Copyright 2010 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS.
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package org.file5.controller.indexer;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.file5.domain.Article;
import org.file5.domain.BaseEntity;
import org.file5.domain.EntityIndex;
import org.file5.search.IdeaExchangeConstants;
import org.file5.search.SearchUtility;
import org.file5.service.ServiceFascade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.google.apphosting.api.DeadlineExceededException;

/**
 * 
 * A controller that handles request for indexing un-indexed entities.
 * 
 * used by cron job defined in cron.xml 
 * 
 * @author Ashish K. Dahiya
 * 
 */

@Controller
@RequestMapping("/indexer")
public class IndexerController {
	private static final Logger logger = Logger
			.getLogger(IndexerController.class);
	@Autowired
	private ServiceFascade sf;

	/**
	 * Index the {@link EntityIndex} entity represented by the key
	 * 
	 * @param request
	 *            {@link HttpServletRequest} object
	 * @param encodedKey
	 *            the key of the entity to be indexed
	 * @return View Name
	 */
	@RequestMapping("/index/Article/{uid}")
	public String indexArticle(HttpServletRequest request,
			@PathVariable String uid) {
		logger.debug("IndexController: Index Entity");
		
		String count = request
				.getHeader(IdeaExchangeConstants.APPENGINE_TASKRETRYCOUNT);
		EntityIndex<Article> entityIndex = sf.getEntityIndexService()
				.findEntityIndex(Article.class, uid);
		if (entityIndex == null) {
			entityIndex = new EntityIndex<Article>(Article.class, uid);
		} else if (entityIndex.getIndexed() != 0) {
			entityIndex.setIndexed(0);
		}
		entityIndex = sf.getBaseService().addUpdate(entityIndex);
		
		if (count == null || count.trim().equals("0")) {
			try {
				indexEntity(entityIndex);
			} catch (DeadlineExceededException e) {
				logger.error("DeadlineExceededException in indexIdeas", e);
			}
		} else {
			logger.debug("Bypassing the entity index as the count is " + count);
		}
		return "queue/queue";
	}



	/**
	 * Index an un-indexed entity and mark it as indexed.
	 * 
	 */
	@RequestMapping("/index")
	public String indexEntity() {
		logger.debug("IndexController: Indexing Entities");

		/* retrieve and un-indexed entity */
		EntityIndex entityIndex = sf.getEntityIndexService()
				.findUnIndexedEntity();
		if (entityIndex != null) {
			indexEntity(entityIndex);
		}
		return "queue/queue";
	}

	/**
	 * Index the {@link EntityIndex} object received as argument
	 * 
	 * @param entityIndex
	 *            {@link EntityIndex} object to be indexed
	 * @return boolean whether he entity was indexed or not
	 */
	private boolean indexEntity(final EntityIndex entityIndex) {
		boolean flag = false;
		try {

			BaseEntity entity = null;
			if (entityIndex != null) {

				/* fetch entity details */
				entity = sf.getBaseService().find(entityIndex.getEntityKey());
			}
			if (entity != null) {
				logger.info("indexing of entity ["
						+ entityIndex.getEntityKey().getKindClassName()
						+ "] with key [" + entityIndex.getEntityKey()
						+ "]  ...");
				/* index the idea using compass */
				boolean entityIndexed = SearchUtility.indexEntity(entity);
				if (entityIndexed) {
					entityIndex.setIndexed(1);
					/* update the entity status from un-indexed to indexed */
					sf.getBaseService().addUpdate(entityIndex);
					logger.info("indexing of entity ["
							+ entityIndex.getEntityKey().getKindClassName()
							+ "] with key [" + entityIndex.getEntityKey()
							+ "]  successful");
					flag = true;
				}
			}

		} catch (DeadlineExceededException e) {
			logger.error("DeadlineExceededException in indexIdeas", e);
		}
		return flag;
	}

}
